跨平台GUI开发 - Qt
开发环境搭建
下载Qt Online Installer,如果Installer(安装或更新)下载速度太慢,可以选择镜像源:
.\qt-unified-windows-x64-4.6.0-online.exe --mirror https://mirrors.tuna.tsinghua.edu.cn/qt/
.\MaintenanceTool.exe --mirror https://mirrors.tuna.tsinghua.edu.cn/qt/
注意:Windows下安装时,需要以管理员权限启动,否则安装Windows Debugger以及Runtime组件时,会一直提示无权限安装失败。
Ubuntu下首先需要安装一下软件包:
sudo apt-get install libgl1-mesa-dev
QML模块化开发
假设我有这么一个模块:
Fluent
├── CMakeLists.txt
├── Rectangle.cpp
├── Rectangle.h
└── qml
└── Text.qml
那么 CMakeLists.txt
应该这么写:
cmake_minimum_required(VERSION 3.29) # 目前发现 CMake 低版本不能正常使用 qt_add_qml_module()
add_library(Fluent
# 其他源文件
)
qt_add_qml_module(Fluent
URI Fluent
VERSION 1.0
PLUGIN_TARGET FluentPlugin # 如果不指定,那么默认就是 TARGET+"plugin",即 Fluentplugin
SOURCES
Rectangle.h Rectangle.cpp
QML_FILES
qml/Text.qml
)
这样会生成两个静态库文件,以Windows下为例,一个是 Fluent.lib
,一个是 Fluentplugin.lib
。所以我们在链接应用程序时,指定这个两个静态库,即可成功使用。
如果是生成动态库文件,则可以将 Fluentplugin.dll
拷贝值可执行应用程序,即可加载。(正确性待确定)
无边框
在 Qt 开发,对于一些较真的 UI 设计师,经常会设计一下需要自定义标题栏的需求。Qt 并没有提供自定义窗口标题栏的实现,更不用说跨平台了。这是因为 Windows 使用 DWM(Desktop Window Manager)管理窗口程序的移动,缩放,标题栏,边框效果。Linux 上窗口管理系统因为发行系统多样化,其则更加多样化了。
在网上也有很多人尝试自己封装跨平台的 Qt 无边框窗口类,例如 QWindowKit,这是中国程序员发起的,我看也有很多人用,不过大部分人都在提 issue
,我也拉下来试用了一下,发现其确实在不同Windows版本之前,不用Qt版本之间,多台显示器(还可能分辨率不一致,DPI不一致)会遇到各种各样的问题,表现不一致甚至带来不能使用的BUG。但不管怎样,它在尝试统一封装跨平台。
最后,就只能自己针对每种平台的桌面窗口管理系统(DWM),进行特定平台的代码开发了。这里可以提一下 FluentUI,他使用 Qt QML 实现了 Fluent 设计风格的 Qt 组件。最开始它也是使用的 QWindowKit
作为无边框实现,但是看 commit
应该是 QWindowKit
作者对该项目做了一些迁移改动,FluentUI
就自己实现了 Windows 下的无边框窗口实现,并自定义标题栏。顺便提一下这个库的控件样式很棒,作者也是中国人。
善用 QVariantList 和 QVariantMap
当我们希望将 C++ 中的数据结构传递到 QML 中时,一般通常做的方式是,使用 Q_OBJECT
、Q_GADGET
实现一个数据结构,好让 QML 能够认识它,但是这样呢,比较麻烦。在一个稍微大一点的项目中,肯定有很多数据结构需要交换。
这个时候使用 QVariantList 和 QVariantMap 可以省去重新实现一个类的繁琐工作。
class Manager : public QObject {
Q_OBJECT
public:
QVariantList availableUsbVideoCameras() const {
QVariantList ret;
auto devices = cameras();
for (auto &device : devices) {
QVariantMap item;
item.insert("name", device.name);
item.insert("path", device.path);
ret << item;
}
return ret;
}
};